﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GuiLibrary.Components;
using Imaginarium.battleSistem;
using Imaginarium.team;
using Microsoft.Xna.Framework;
using GameEngine.Scenes;
using GuiLibrary.layouts;
using Microsoft.Xna.Framework.Graphics;
using GuiLibrary;

namespace Imaginarium.gui
{
    public class BattleInfoGui: Gui, IOnCharacterAffected
    {
        TurnExpert turnExpert;

        #region Constructors
        public BattleInfoGui(TurnExpert turnExpert):
        base()
        {
            this.turnExpert = turnExpert;
            SubjectCharacterStat.getInstance().addCharAffectedListener(this);
        }
        ~BattleInfoGui() 
        {
            SubjectCharacterStat.getInstance().removeCharAffectedListener(this);
        }
        #endregion

        #region Functionality
        public override void LoadContent()
        {
            #region ObtainRequiredData
            Team enemyTeam = turnExpert.m_Teams[0], playerTeam = turnExpert.m_Teams[1];
            List<Element> enemyTeamElements = new List<Element>(enemyTeam.characters.Count),
                playerTeamElements = new List<Element>(playerTeam.characters.Count);
            foreach (Character character in enemyTeam.characters) 
                enemyTeamElements.Add(new ImaginariumElement(character));
            foreach (Character character in playerTeam.characters)
                playerTeamElements.Add(new ImaginariumElement(character));
            #endregion

            #region CreateGuiComponents
            basePanel = new Panel(position, GUIParameters.backgroundBattleInfoGUI());
            SpriteFont font = Imaginarium.ImaginariumGame.getInstance().Content.Load<SpriteFont>(CodeParameters.battleInfoFont);
            List<Component> textComponents = new List<Component>();
            Panel enemiesInfoPanel = new Panel(basePanel), playerInfoPanel = new Panel(basePanel), playerInfoLinePanel;

            foreach (Element element in enemyTeamElements)
                enemiesInfoPanel.components.Add(new SelectableLabel(enemiesInfoPanel, new Vector2(), new Text(font, element.name, Color.White, GameEngine.animations.OriginType.LEFT_UP),element));
            foreach (Element element in playerTeamElements)
            {
                Character character = (Character)element.associatedObject;

                playerInfoLinePanel = new SelectablePanel(playerInfoPanel, element);
                playerInfoLinePanel.layout = new ListLayout(playerInfoLinePanel, GUIParameters.marginsZERO, GUIParameters.weightsPlayerLineInfoGUI, false, null, null, null);
                playerInfoLinePanel.layout.flashPointedElement = false;
                //playerInfoLinePanel.layout.refresh();

                SelectableLabel name = new SelectableLabel(playerInfoLinePanel, new Vector2(), new Text(font, element.name, Color.White, GameEngine.animations.OriginType.LEFT_UP), element);
                SelectableLabel life = new SelectableLabel(playerInfoLinePanel, new Vector2(), new Text(font, character.hp.ToString(), Color.White, GameEngine.animations.OriginType.LEFT_UP), element);
                SelectableLabel mana = new SelectableLabel(playerInfoLinePanel, new Vector2(), new Text(font, character.mp.ToString(), Color.White, GameEngine.animations.OriginType.LEFT_UP), element);

                playerInfoLinePanel.components.Add(name);
                playerInfoLinePanel.components.Add(life);
                playerInfoLinePanel.components.Add(mana);
                playerInfoPanel.components.Add(playerInfoLinePanel);
            }
            basePanel.layout = new ListLayout(basePanel, GUIParameters.marginsZERO, GUIParameters.weightsBattleInfoGUI, false, null, null, null);
            //basePanel.layout.refresh();
            enemiesInfoPanel.layout = new ListLayout(enemiesInfoPanel, GUIParameters.marginsEnemiesInfoGUI, true, null, null, null);
            enemiesInfoPanel.layout.flashPointedElement = false;
            //enemiesInfoPanel.layout.refresh();
            playerInfoPanel.layout = new ListLayout(playerInfoPanel, GUIParameters.marginsPlayersInfoGUI, true, null, null, null);
            playerInfoPanel.layout.flashPointedElement = false;
            //playerInfoPanel.layout.refresh();

            basePanel.components.Add(enemiesInfoPanel);
            basePanel.components.Add(playerInfoPanel);
            basePanel.refresh();
            #endregion
        }
        public void setSelectedPlayer(Character selPlayer)
        {
            if (selPlayer == null)
            {
                turnOffFlashing();
                return;
            }
            int i = 0;
            turnExpert.startNewBattleCommand();
            foreach(Character c in turnExpert.m_Teams[1].characters)
            {
                if(c==selPlayer)
                {
                    turnExpert.currentCharacter = i;
                    break;
                }
                i++;
            }
            
            getPlayersPanel().layout.flashPointedElement = true;
            ISelectableComponent selPlayerComponent = (ISelectableComponent)getPlayerPanel(turnExpert.getCurrentCharacterInAction());
            if(selPlayerComponent!= null)selPlayerComponent.onComponentPointed();
            int existingCharIndex = 0; //to consider only players showable in the screen (those who don't dissapear after dying)
            List<Character> curTeamChars = turnExpert.getCurrentTeamInAction().characters;
            for (int j = 0; j < curTeamChars.Count ; j++)
            {
                if (curTeamChars[j].isDead() && curTeamChars[j].dissapearAtDying)
                    continue;
                if (((ISelectableComponent)getPlayersPanel().components[existingCharIndex]).getAssociatedElement().associatedObject == selPlayer)
                {
                    ((ISelectableComponent)getPlayersPanel().components[existingCharIndex]).onComponentPointed();
                }
                else {
                    ((ISelectableComponent)getPlayersPanel().components[existingCharIndex]).onComponentUnpointed();
                }
                existingCharIndex++;
            }
        }
        private void turnOffFlashing() 
        {
            foreach (Component c in getPlayersPanel().components)
                foreach (Component c1 in ((Panel)c).components)
                    ((ISelectableComponent)c1).onComponentUnpointed();
        }
        private Panel getPlayersPanel() 
        {
            return (Panel)basePanel.components[1];
        }
        private Panel getPlayerPanel(Character player) 
        {
            foreach (Component playerInfoLineComponent in getPlayersPanel().components) 
            {
                if(((SelectablePanel)playerInfoLineComponent).elementAssociated.associatedObject == player)
                    return (Panel)playerInfoLineComponent;
            }
            return null;
        }
        private Panel getEnemiesPanel()
        {
            return (Panel)basePanel.components[0];
        }
        private Label getEnemyLabel(Character enemy)
        {
            foreach (Component enemyNameComponent in getEnemiesPanel().components)
            {
                if (((SelectableLabel)enemyNameComponent).elementAssociated.associatedObject == enemy)
                    return (Label)enemyNameComponent;
            }
            return null;
        }
        #endregion

        #region Events

        public override void onSelectedElement(Element e)
        { }

        #region IOnCharacterAffected Members
        public void onCharacterAffected(Character charAffected)
        {
            Panel playerInfoLineComponent = getPlayerPanel(charAffected);
            if (playerInfoLineComponent != null) 
            {
                SelectableLabel hpLabel = (SelectableLabel)playerInfoLineComponent.components[1];
                SelectableLabel mpLabel = (SelectableLabel)playerInfoLineComponent.components[2];
                hpLabel.text.text = charAffected.hp.ToString();
                mpLabel.text.text = charAffected.mp.ToString();
                if (charAffected.isDead() && charAffected.dissapearAtDying)
                {
                    Panel parentPanel = (Panel)playerInfoLineComponent.parent;
                    parentPanel.eraseComponent(playerInfoLineComponent);
                }
            }
            Label enemyNameComponent = getEnemyLabel(charAffected);
            if (enemyNameComponent != null) 
            {
                if (charAffected.isDead() && charAffected.dissapearAtDying) 
                {
                    Panel parentPanel = (Panel)enemyNameComponent.parent;
                    parentPanel.eraseComponent(enemyNameComponent);
                }
            }
        }
        #endregion       

        #endregion



 
    }
}
